﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;
using System.Net.NetworkInformation;
using Microsoft.Win32;
using System.IO;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace QRWin
{

    // private TextBox appSecretTxt;

    //  private AppSettingsReader appReader = new AppSettingsReader();

    /*
           ${host}/qr/order/confrim? signature = { sign }     POST
            http body
            {orderId:${orderId},
             token:${token},
             pushTime:${pushTime},
             appId:${appId} 

            },
       **/
    public partial class Form1 : Form
    {

        private AppSettingsReader appReader = new AppSettingsReader();

        private bool isRunning = false;

        private JsonSerializerSettings serializerSettings;

        private long timeStamp; 

        BardCodeHooK BarCode = new BardCodeHooK();

        private delegate void ShowInfoDelegate(BardCodeHooK.BarCodes barCode);


        private int radioVal = 0;

        public Form1()
        {
            InitializeComponent();
            initBox();
            BarCode.BarCodeEvent += new BardCodeHooK.BardCodeDeletegate(BarCode_BarCodeEvent);
            timeStamp = HttpUtils.GetCurrentDateTime();

            StartHook();



        }

        private void ShowInfo(BardCodeHooK.BarCodes barCode)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new ShowInfoDelegate(ShowInfo), new object[] { barCode });
            }
            else
            {
                Console.WriteLine(barCode.IsValid ? barCode.BarCode : "");
                Logger.WriteLog("BarCode=" + barCode.BarCode);
                Logger.WriteLog("BarCode IsValid=" + barCode.IsValid);
                qrTxt.AppendText("BarCode=" + barCode.BarCode);
                qrTxt.AppendText("BarCode IsValid=" + barCode.IsValid+"\r\n");
                int timeSpan = GetNowTimeSpanSec(timeStamp);
                Logger.WriteLog("TIMESPAN SEC=" + timeSpan);
                if (timeSpan <= 3)
                {
                    infoTxt.AppendText("\n频发通信，通信间隔3秒 TIME："+HttpUtils.GetCurrentDateTimeStr());
                    return;
                }

                if (barCode.IsValid&&timeSpan > 3)
                {
                    //post to server
                    timeStamp = HttpUtils.GetCurrentDateTime();
                    string qrStr = barCode.BarCode;
                    PostToServer(qrStr.Replace("\n", string.Empty).Replace("\r", string.Empty));
                }
               
            }
        }


        void BarCode_BarCodeEvent(BardCodeHooK.BarCodes barCode)
        {
            ShowInfo(barCode);
        }

        private void initBox() {

           

            string appSecret = (string)appReader.GetValue("appSecret", typeof(string));
            appSecretTxt.Text = appSecret;

            string appId = (string)appReader.GetValue("appId", typeof(string));
            appIdTxt.Text = appId;

            string url = (string)appReader.GetValue("url", typeof(string));
            urlTxt.Text = url;

            string macAddr = (string)appReader.GetValue("macAddr", typeof(string));
            macAddrTxt.Text = getMacAddress();


            serializerSettings = new JsonSerializerSettings
            {
                // 设置为驼峰命名
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
            serializerSettings.NullValueHandling = NullValueHandling.Ignore;

            Logger.WriteLog("init is ok");
        }

        private void StartHook()
        {

            Logger.WriteLog("appSecret="+GetValue("appSecret"));
         
            BarCode.Start();
            MessageBox.Show("Service is Running", "QRCodeReader", MessageBoxButtons.OK);
          //  button1.Text = "运行中";
           // button1.Enabled = false;
            isRunning = true;
            button3.Focus();
        }



        private void button2_Click(object sender, EventArgs e)
        {
    

            MessageBox.Show("Communication Test", "QRCodeReader", MessageBoxButtons.OK);
            Logger.WriteLog("TIMESPAN SEC=" + GetNowTimeSpanSec(timeStamp));
            timeStamp = HttpUtils.GetCurrentDateTime();
            PostToServer("123123;ir0g8t;1535334490038;ykd");
            button3.Focus();



        }


        private void PostToServer(string qrStr) {
 
            button3.Focus();
            string[] args=qrStr.Split(';');
            if (args == null || args.Length != 4|| args[3]!= "ykd")
            {
                infoTxt.Text="\n参数错误，请确认二维码是否正确... timestamp=" + HttpUtils.GetCurrentDateTimeStr();
                Logger.WriteLog("参数错误，请确认二维码是否正确,qr code="+ qrStr+"timestamp = "+ HttpUtils.GetCurrentDateTimeStr());
                return;
            }

            HttpBody2Server body = new HttpBody2Server();

            body.OrderId = args[0];
            body.Token = args[1];
            body.PushTime = args[2];
            body.MacAddr = macAddrTxt.Text;
            body.AppId = appIdTxt.Text;
            body.AppSecret = appSecretTxt.Text;
            body.OrderStatus = radioVal+"";

            // infoTxt.Text = "-----------------------------------";
            infoTxt.Text="处理中... 订单号=" + body.OrderId;
            
            JObject json = PostJSON(args, body);

            string retStr=json.Value<string>("result");

            if (retStr == "200")
            {
                infoTxt.AppendText("\n"+json.Value<string>("message") + ", timestamp=" + HttpUtils.GetCurrentDateTimeStr());
                radio1.Checked = false;
                radioButton1.Checked = false;
                radioButton2.Checked = false;
            }
            else if (retStr == "10")
            {

                infoTxt.AppendText("\n到店付款..." + json.Value<string>("message") + ", timestamp=" + HttpUtils.GetCurrentDateTimeStr());
                //DialogResult result = MessageBox.Show(json.Value<string>("message"),"药快到", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                //if (result == DialogResult.Yes)
                //{
                //    body.OrderStatus = "1";
                //    json = PostJSON(args, body);
                //    retStr = json.Value<string>("result");

                //    if (retStr == "200")
                //    {
                //        infoTxt.AppendText("\n"+json.Value<string>("message") + ", timestamp=" + HttpUtils.GetCurrentDateTimeStr());
                //    }else
                //    {
                //        infoTxt.AppendText("\n处理失败..." + json.Value<string>("message") + ", timestamp=" + HttpUtils.GetCurrentDateTimeStr());
                //    }


                //}
                //else
                //{
                //    infoTxt.AppendText("\n处理结束..." + ", timestamp=" + HttpUtils.GetCurrentDateTimeStr());
                //}
            }
            else
            {
                infoTxt.AppendText("\n处理失败..." + json.Value<string>("message") + ", timestamp=" + HttpUtils.GetCurrentDateTimeStr());
                radio1.Checked = false;
                radioButton1.Checked = false;
                radioButton2.Checked = false;
            }


        }


        private JObject PostJSON(string[] args, HttpBody2Server body)
        {
 
            string strContent = JsonConvert.SerializeObject(body, serializerSettings);
            string url = urlTxt.Text + "?sign=" + HttpUtils.getSign(strContent, appSecretTxt.Text) + "&push_time=" + HttpUtils.GetCurrentDateTime();
            Logger.WriteLog("URL=" + url);
            Logger.WriteLog("JSON=" + strContent);

            JObject json = HttpUtils.Post(url, strContent);

            return json;

        }


        private void setAppSettings(string key,string val)
        {
            //获取Configuration对象
            Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            //根据Key读取<add>元素的Value
            //string name = config.AppSettings.Settings["name"].Value;
            //  写入<add>元素的Value
            config.AppSettings.Settings[key].Value = val;
            //增加<add>元素
            //config.AppSettings.Settings.Add("url", "http://www.fx163.net");
            //删除<add>元素
            //config.AppSettings.Settings.Remove("name");
            //一定要记得保存，写不带参数的config.Save()也可以
            config.Save(ConfigurationSaveMode.Full);
            //刷新，否则程序读取的还是之前的值（可能已装入内存）
            System.Configuration.ConfigurationManager.RefreshSection("appSettings");

          
        }

        public string getMacAddress()
        {
            string macAddress = null;
            try
            {
                NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                foreach (NetworkInterface adapter in nics)
                {
                    if (adapter.NetworkInterfaceType.ToString().Equals("Ethernet")) //是以太网卡
                    {
                        string fRegistryKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter.Id + "\\Connection";
                        RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false);
                        if (rk != null)
                        {
                            // 区分 PnpInstanceID     
                            // 如果前面有 PCI 就是本机的真实网卡    
                            // MediaSubType 为 01 则是常见网卡，02为无线网卡。    
                            string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();
                            int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));
                            if (fPnpInstanceID.Length > 3 && fPnpInstanceID.Substring(0, 3) == "PCI") //是物理网卡
                            {
                                macAddress = adapter.GetPhysicalAddress().ToString();
                                break;
                            }
                            else if (fMediaSubType == 1) //虚拟网卡
                                continue;
                            else if (fMediaSubType == 2) //无线网卡(上面判断Ethernet时已经排除了)
                                continue;
                        }
                    }
                }
            }
            catch
            {
                macAddress = null;
            }
            return macAddress;
        }

       






        public static string GetValue(string key)
        {
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (config.AppSettings.Settings[key] == null)
                return "";
            else
                return config.AppSettings.Settings[key].Value;
        }




        public static void SetValue(string key, string value)
        {
            //增加的内容写在appSettings段下 <add key="RegCode" value="0"/>  
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (config.AppSettings.Settings[key] == null)
            {
                config.AppSettings.Settings.Add(key, value);
            }
            else
            {
                config.AppSettings.Settings[key].Value = value;
            }
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");//重新加载新的配置文件   
        }

        private void button3_Click(object sender, EventArgs e)
        {
           // if (isRunning)
            //{
               // BarCode.Stop();
                //button1.Text = "启动";
                //button1.Enabled = true;
                //isRunning = false;
                //MessageBox.Show("Stop Service Now","QRCodeReader", MessageBoxButtons.OK);

            //}
        }

  

        public  int GetNowTimeSpanSec(long _time)
        {
 
            return (int)(HttpUtils.GetCurrentDateTime()-_time)/1000;
        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void saveBtn_Click(object sender, EventArgs e)
        {
            SetValue("url", urlTxt.Text);
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            radioVal = 2;
        }

        private void radio1_CheckedChanged(object sender, EventArgs e)
        {
            radioVal = 1;
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            radioVal = 0;
        }
    }

    public partial class HttpBody2Server
    {
        
        private string orderId ;
        private string token;
        private string pushTime ;
        private string macAddr ;
        private string appId ;
        private string appSecret;

        private string orderStatus; // 1 为 已经确认到店收款的 订单 

        public string OrderId
        {
            get
            {
                return orderId;
            }

            set
            {
                orderId = value;
            }
        }

        public string Token
        {
            get
            {
                return token;
            }

            set
            {
                token = value;
            }
        }

        public string PushTime
        {
            get
            {
                return pushTime;
            }

            set
            {
                pushTime = value;
            }
        }

        public string MacAddr
        {
            get
            {
                return macAddr;
            }

            set
            {
                macAddr = value;
            }
        }

        public string AppId
        {
            get
            {
                return appId;
            }

            set
            {
                appId = value;
            }
        }

        public string AppSecret
        {
            get
            {
                return appSecret;
            }

            set
            {
                appSecret = value;
            }
        }

        public string OrderStatus
        {
            get
            {
                return orderStatus;
            }

            set
            {
                orderStatus = value;
            }
        }
    }
}
